home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / answers / polygonoffset.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  9.5 KB  |  403 lines

  1. /*
  2.  * Copyright 1996, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* depth.c - open a window and clear the background.
  19.  *    Set up callbacks to handle keyboard input.
  20.  *      Model some objects.  Use perspective projection.
  21.  *    Use independent modeling transformations to position objects.
  22.  *    Added reshape callback to reset the viewport and viewing volume.
  23.  *    Add depth buffering.
  24.  *
  25.  *    F1 key            - print help information
  26.  *    SPACE key        - generates a random background color
  27.  *    <f> key            - toggle front/back face culling
  28.  *    <s> key            - toggle smooth/flat shading
  29.  *    Escape Key        - exit program
  30.  */
  31. #include <GL/gl.h>
  32. #include <GL/glu.h>
  33. #include <GL/glut.h>
  34.  
  35. #include <stdio.h>
  36. #include <math.h>
  37.  
  38. /* Function Prototypes */
  39.  
  40. GLvoid initgfx( GLvoid );
  41. GLvoid keyboard( GLubyte, GLint, GLint );
  42. GLvoid specialkeys( GLint, GLint, GLint );
  43. GLvoid reshape( GLsizei, GLsizei );
  44. GLvoid drawScene( GLvoid );
  45.  
  46. void checkError( char * );
  47. void printHelp( char * );
  48.  
  49. /* Global Variables */
  50.  
  51. static char *progname; 
  52.  
  53. /* Global Definitions */
  54.  
  55. #define KEY_ESC    27    /* ascii value for the escape key */
  56.  
  57. void
  58. main( int argc, char *argv[] )
  59. {
  60.     GLsizei width, height;
  61.  
  62.     glutInit( &argc, argv );
  63.  
  64.     /* create a window that is 1/4 the size of the screen,
  65.      * and position it in the middle of the screen.
  66.      */
  67.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  68.     height = glutGet( GLUT_SCREEN_HEIGHT );
  69.     glutInitWindowPosition( width / 4, height / 4 );
  70.     glutInitWindowSize( width / 2, height / 2 );
  71.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH );
  72.     glutCreateWindow( argv[0] );
  73.  
  74.     initgfx();
  75.  
  76.     glutReshapeFunc( reshape );
  77.     glutKeyboardFunc( keyboard );
  78.     glutSpecialFunc( specialkeys );
  79.     glutDisplayFunc( drawScene ); 
  80.  
  81.     progname = argv[0];
  82.  
  83.     printHelp( progname );
  84.  
  85.     glutMainLoop();
  86. }
  87.  
  88. void
  89. printHelp( char *progname )
  90. {
  91.     fprintf(stdout, 
  92.         "\n%s - create a scene and handle resizing\n\n"
  93.         "F1 key        - print help information\n"
  94.         "SPACE Key    - generates a random background color\n"
  95.         "<f> key        - toggle front/back face culling\n"
  96.         "<s> key        - toggle smooth/flat shading\n"
  97.         "Escape Key    - exit the program\n\n",
  98.         progname);
  99. }
  100.  
  101. GLvoid
  102. initgfx( GLvoid )
  103. {
  104.  
  105.     /* set clear color to blue */
  106.     glClearColor( 0.0, 0.0, 1.0, 1.0 );
  107.  
  108.     /* enable the depth buffer */
  109.     glEnable( GL_DEPTH_TEST );
  110.  
  111.     /* enable the face culling */
  112.     glEnable( GL_CULL_FACE );
  113. }
  114.  
  115. GLvoid 
  116. reshape( GLsizei width, GLsizei height )
  117. {
  118.     GLdouble    aspect;
  119.  
  120.     glViewport( 0, 0, width, height );
  121.  
  122.     /* compute aspect ratio */
  123.     aspect = (GLdouble) width / (GLdouble) height;
  124.  
  125.     glMatrixMode( GL_PROJECTION );
  126.  
  127.     /* Reset world coordinates first ... */
  128.     glLoadIdentity();
  129.  
  130.     /* Reset the viewing volume based on the new aspect ratio */
  131.     gluPerspective( 45.0, aspect, 3.0, 7.0 );
  132.  
  133.     glMatrixMode( GL_MODELVIEW );
  134. }
  135.  
  136. void 
  137. checkError( char *label )
  138. {
  139.     GLenum error;
  140.     while ( (error = glGetError()) != GL_NO_ERROR )
  141.         printf( "%s: %s\n", label, gluErrorString(error) );
  142. }
  143.  
  144. GLvoid 
  145. keyboard( GLubyte key, GLint x, GLint y )
  146. {
  147.     static GLboolean flat = GL_FALSE;
  148.     static GLboolean cullFront = GL_FALSE;
  149.  
  150.     switch (key) {
  151.     case ' ':    /* SPACE key */
  152.         /* generate a random background color */
  153.         glClearColor( drand48(), drand48(), drand48(), 1.0 ); 
  154.         glutPostRedisplay();
  155.         break;
  156.     case 'f':    /* f key */
  157.         /* toggle between back and front face culling */
  158.         cullFront = !cullFront;
  159.         if (cullFront) {
  160.             glCullFace( GL_FRONT );
  161.             printf("Culling FRONT faces\n");
  162.         } else { 
  163.             glCullFace( GL_BACK );
  164.             printf("Culling BACK faces\n");
  165.         }
  166.         glutPostRedisplay();
  167.         break;
  168.     case 's':    /* s key */
  169.         /* toggle between smooth and flat shading */
  170.         flat = !flat;
  171.         if (flat)
  172.             glShadeModel( GL_FLAT );
  173.         else 
  174.             glShadeModel( GL_SMOOTH );
  175.         glutPostRedisplay();
  176.         break;
  177.     case KEY_ESC:    /* Exit when the Escape key is pressed */
  178.         exit(0);
  179.     }
  180. }
  181.  
  182. GLvoid 
  183. specialkeys( GLint key, GLint x, GLint y )
  184. {
  185.     switch (key) {
  186.     case GLUT_KEY_F1:    /* Function key #1 */
  187.         /* print help information */
  188.         printHelp( progname );
  189.         break;
  190.     }
  191. }
  192.  
  193. GLvoid
  194. drawWindow()
  195. {
  196.     /* window */
  197.     static GLfloat v0[] = { 0.0, 0.4 };
  198.     static GLfloat v1[] = { 0.0, 0.0 };
  199.     static GLfloat v2[] = { 0.1, 0.4 };
  200.     static GLfloat v3[] = { 0.1, 0.0 };
  201.     static GLfloat v4[] = { 0.2, 0.4 };
  202.     static GLfloat v5[] = { 0.2, 0.0 };
  203.  
  204.     /* draw 2 quadrilateral strip to make a window */
  205.     glBegin( GL_QUAD_STRIP );
  206.         glColor3f( 1.0, 0.0, 0.0 );
  207.         glVertex2fv (v0);
  208.         glColor3f( 0.9, 0.0, 1.0 );
  209.         glVertex2fv (v1);
  210.         glColor3f( 0.8, 0.1, 0.0 );
  211.         glVertex2fv (v2);
  212.         glColor3f( 0.7, 0.2, 1.0 );
  213.         glVertex2fv (v3);
  214.         glColor3f( 0.6, 0.3, 0.0 );
  215.         glVertex2fv (v4);
  216.         glColor3f( 0.5, 0.4, 1.0 );
  217.         glVertex2fv (v5);
  218.         glColor3f( 0.4, 0.5, 0.0 );
  219.     glEnd();
  220. }
  221.  
  222. /* draw a "circle" using a triangle fan; set the
  223.  * center of the circle to white, and the outside
  224.  * to the color passed in
  225.  */
  226. GLvoid
  227. drawFan( GLfloat *color )
  228. {
  229.     /* Draw a triangle fan centered a the current coordinate
  230.      * system origin 
  231.      */
  232.     glBegin( GL_TRIANGLE_FAN );
  233.         glColor3f( 1.0, 1.0, 1.0 );
  234.         glVertex2f( 0.0, 0.0 );
  235.         glColor3fv( color );
  236.         glVertex2f( 0.0, -0.2 );
  237.         glVertex2f( 0.2, -0.1 );
  238.         glVertex2f( 0.2, 0.1 );
  239.         glVertex2f( 0.0, 0.2 );
  240.         glVertex2f( -0.2, 0.1 );
  241.         glVertex2f( -0.2, -0.1 );
  242.         glVertex2f( 0.0, -0.2 );
  243.     glEnd();
  244. }
  245.  
  246. /* draw a flower with the base of the stem 
  247.  * at the current location 
  248.  */
  249. GLvoid
  250. drawFlower( GLfloat *color )
  251. {
  252.     static GLfloat darkgreen[] = { 0.0, 0.25, 0.0 };
  253.     /* draw the stem with 2 leaves */
  254.  
  255.     glColor3fv( darkgreen );
  256.     glBegin( GL_LINES );
  257.         glVertex2f( 0.0, 0.0 );         /* stem */
  258.         glVertex2f( 0.0, 0.25 );
  259.         glVertex2f( 0.0, 0.1 );         /* leaf */
  260.         glVertex2f( 0.05, 0.15 ); 
  261.         glVertex2f( 0.0, 0.05 );     /* leaf */
  262.         glVertex2f( -0.05, 0.2 );
  263.     glEnd();
  264.  
  265. #ifdef    GL_EXT_polygon_offset
  266.     /* make sure the flower heads are in front of the stems */
  267.     glEnable( GL_POLYGON_OFFSET_EXT );
  268.     glPolygonOffsetEXT( 0.5, -0.0002 );
  269. #endif
  270.     glPushMatrix();
  271.         /* move to the top of the stem */
  272.         glTranslatef( 0.0, 0.25, 0.0 );
  273.  
  274.         /* use a scaled triangle fan for the flower head */
  275.         glScalef( 0.1, 0.1, 1.0 );
  276.         drawFan( color );  
  277.     glPopMatrix();
  278. #ifdef    GL_EXT_polygon_offset
  279.     glDisable( GL_POLYGON_OFFSET_EXT );
  280. #endif
  281. }
  282.  
  283. /* draw a house centered at the current origin;
  284.  * the bounding box for the house is 1.0 x 2.0 units
  285.  */
  286. GLvoid
  287. drawHouse()
  288. {
  289.     /* draw a 3D house */
  290.     glColor3f( 1.0, 1.0, 1.0 ); /* white */
  291.     SolidBox( 1.0, 1.5, 1.0 );
  292.  
  293.     glPushMatrix();
  294.         /* move to the peak of the roof */
  295.         glTranslatef( 0.0, 1.25, 0.0 );
  296.  
  297.         /* draw a triangle fan for the roof */
  298.         glColor3f( 0.0, 0.0, 0.0 ); /* black */
  299.         glBegin( GL_TRIANGLE_FAN );
  300.             glVertex3f( 0.0, 0.0, 0.0 ); /* peak */
  301.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  302.             glVertex3f( 0.5, -0.5, 0.5 ); /* front right */
  303.             glVertex3f( 0.5, -0.5, -0.5 ); /* back right */
  304.             glVertex3f( -0.5, -0.5, -0.5 ); /* back left */
  305.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  306.         glEnd();
  307.     glPopMatrix();
  308.  
  309. #ifdef    GL_EXT_polygon_offset
  310.     /* make sure the door and windows are in front of the house */
  311.     glEnable( GL_POLYGON_OFFSET_EXT );
  312.     glPolygonOffsetEXT( 0.5, -0.0002 );
  313. #endif
  314.     glPushMatrix();
  315.         /* move to the front of the house */
  316.         glTranslatef( 0.0, 0.0, 0.5 );
  317.  
  318.         /* draw the door */
  319.         glColor3f( 0.5, 0.2, 0.1 ); /* brown */
  320.         glRectf( -0.2, -0.75, 0.2, 0.0 );
  321.  
  322.         glPushMatrix();
  323.             /* move to the location for the left window */
  324.             glTranslatef( -0.4, 0.2, 0.0 );
  325.             drawWindow();
  326.         glPopMatrix();
  327.  
  328.         glPushMatrix();
  329.             /* move to the location for the right window */
  330.             glTranslatef( 0.2, 0.2, 0.0 );
  331.             drawWindow();
  332.         glPopMatrix();
  333.     glPopMatrix();
  334. #ifdef    GL_EXT_polygon_offset
  335.     glDisable( GL_POLYGON_OFFSET_EXT );
  336. #endif
  337. }
  338.  
  339. GLvoid
  340. drawScene( GLvoid )
  341. {
  342.     static GLfloat red[] = { 1.0, 0.0, 0.0 };
  343.     static GLfloat magenta[] = { 1.0, 0.0, 1.0 };
  344.     static GLfloat yellow[] = { 1.0, 1.0, 0.0 };
  345.     static GLfloat blue[] = { 0.0, 0.0, 1.0 };
  346.     static GLfloat green[] = { 0.0, 1.0, 0.0 };
  347.     static GLfloat darkgreen[] = { 0.0, 0.25, 0.0 };
  348.  
  349.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  350.  
  351.     glPushMatrix();
  352.  
  353.         /* move inside the viewing volume */
  354.         glTranslatef( 0.0, 0.0, -4.0 );
  355.  
  356.         /* draw the ground in different shades of green */
  357.         glBegin( GL_POLYGON );
  358.             glColor3fv( green );
  359.             glVertex2f( -3.0, -2.0 );
  360.             glVertex2f( 3.0, -2.0 );
  361.             glColor3fv( darkgreen );
  362.             glVertex2f( 3.0, 0.0 );
  363.             glVertex2f( -3.0, 0.0 );
  364.         glEnd();
  365.  
  366.         /* draw the house */
  367.         glPushMatrix();
  368.             /* move to where the center of the house should be */
  369.             glTranslatef( -0.5, 0.0, 0.0 );
  370.  
  371.             /* shrink the house slightly */
  372.             glScalef( 0.7, 0.7, 0.7 );
  373.             drawHouse();
  374.         glPopMatrix();
  375.  
  376.         /* draw the sun */
  377.         glPushMatrix();
  378.             /* move to the location of the sun */
  379.             glTranslatef( 2.0, 2.0, -1.5 );
  380.             glColor3fv( yellow );
  381.             glutSolidSphere( 0.2, 8, 15 );
  382.         glPopMatrix();
  383.  
  384.         /* draw several tulips in the foreground */
  385.         glPushMatrix();
  386.             glTranslatef( 1.0, -1.0, 1.0 );
  387.             drawFlower( red );
  388.             glTranslatef( 0.0, 0.0, -0.5 );
  389.             drawFlower( yellow );
  390.         glPopMatrix();
  391.         glPushMatrix();
  392.             glTranslatef( -1.0, -1.0, 1.0 );
  393.             drawFlower( blue );
  394.             glTranslatef( 0.0, 0.0, -0.5 );
  395.             drawFlower( magenta );
  396.         glPopMatrix();
  397.  
  398.     glPopMatrix();
  399.  
  400.     checkError( "drawScene" );
  401.     glFlush();
  402. }
  403.